package com.zkh.myframe.core;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zkh.myframe.exception.BaseException;
import com.zkh.myframe.interceptor.Interceptor;
import com.zkh.myutils.utils.StringUtils;

/**
 * 链对象，本框架核心方法之一
 * @author zkh
 */
public class Chain {
	//拦截器链
	static List<Interceptor> interceptorChainList = new ArrayList<>();
	// 计次
	private int count = 0;

	// 一系列属性
	private HttpServletRequest request;
	private HttpServletResponse response;
	private List<Interceptor> chains;
	private Object[] controllerName;

	/**
	 * 构造函数
	 * @param request ServletRequest对象
	 * @param response ServletResponse对象
	 * @param interceptorChains 拦截器链
	 * @param controllerName [urlPattern, methodsAndArguments]
	 */
	public Chain(ServletRequest request, ServletResponse response, Object[] controllerName) {
		this.request = (HttpServletRequest) request;
		this.response = (HttpServletResponse) response;
		this.chains = new ArrayList<>(interceptorChainList);
		this.controllerName = controllerName;
	}

	/**
	 * 执行下一个拦截器
	 */
	public void nextChain() throws Exception {
		// 判断是否有拦截器，检查拦截器是否执行完毕，如果未执行完，则执行拦截器
		if (chains != null && chains.size() > 0 && count < chains.size()) {
			// 实例化拦截器
			try {
				// 执行方法
				chains.get(count++).doFilter(request, response, this);
			} catch (Exception te) {
				// 自定义业务异常
				if (te instanceof BaseException) {
					// 强转自定义业务异常
					BaseException e = (BaseException) te;
					// 错误页面
					String excepPage = FrameConfigure.getBaseExceptionPage();
					// 404
					if (e.getErrorCode() == 404) {
						response.sendError(404, "你请求的页面不存在");
					} else if (e.getErrorCode() != 999 && !StringUtils.isEmpty(excepPage)) {
						// 错误信息
						request.setAttribute("e", e);
						// 跳转到错误页面
						request.getRequestDispatcher(excepPage).forward(request, response);
					} else {
						throw e;
					}
				} else {
					throw te instanceof Exception ? (Exception) te : new Exception(te);
				}
			}
		}
		// 拦截器已执行完毕，则执行应用
		else {
			ControllerHandler.controllerAccess(request, response, controllerName);
		}
	}
}
